home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
manchest.lha
/
MANCHESTER
/
usenet
/
st80_pre4
/
pretty-print
/
exampleCommands.st
< prev
next >
Wrap
Text File
|
1993-07-24
|
25KB
|
1,257 lines
"\TeXCommand
\startClassDef{Boiler}{Components}
\setVersion{1:48 on Oct 4, 1991}
\setHierarchy{{Components}{TestHeating}{Object}}
\endClassDef
"!
Components subclass: #Boiler
instanceVariableNames:
'oilValve ignitor tempSensor oilFlowSensor
combustionSensor internalModels '
classVariableNames: ''
poolDictionaries: ''.
"\TeXCommand
\startClassSection{Comment}
"!
Boiler
comment:
'
This is a Furnace Boiler. It is composed of a number
of small parts:
oilValve controls whether oil is flowing
ignitor ignites the boiler
tempSensor monitors the temperature in the boiler
oilFlowSensor
combustionSensor detect faults
all of the above are types of Informers, as are most
of this system.
Also see diagram: BoilerDiagram.eps
'. !
"\TeXCommand
\diagram{BoilerDiagram.eps}
"!
"\TeXCommand
\startClassSection{Summary}
"!
"
************* Class Methods Summary ************
----Public----
new
*********** Instance Methods Summary ***********
----Public----
faultExists Do my sensors presently detect a fault
initialize
release
resetFault Try to reset the fault yourself
turnOff
turnOn
Dependency
update: who
update: who with: detail
Widget
initWindowSize Tell the topWidget what size to open to
modelReleased: who
The top Pane lost a model for one of its subPanes.
The whole window should close.
openView create a boiler interface
----Limited----
combustionSensor My combustionSensor
ignitor my ignitor
oilFlowSensor
oilValve
tempSensor My temp sensor
***************** End Summary ******************
"!
!Boiler class methods !
new
<<Public>>
^super new initialize! !
!Boiler methods !
combustionSensor
<<Limited>>
"My combustionSensor"
^combustionSensor!
faultExists
<<Public>>
"Do my sensors presently detect a fault "
^(oilFlowSensor value) | (combustionSensor value)!
ignitor
<<Limited>>
"my ignitor"
^ignitor!
initialize
<<Public>>
| sim |
oilValve := Valve new.
oilValve addDependent: self.
ignitor := Ignitor new.
oilFlowSensor := BooleanInformer new.
oilFlowSensor addDependent: self.
combustionSensor := BooleanInformer new.
combustionSensor addDependent: self.
tempSensor := IntervalInformer new.
tempSensor
min: 60 max: 300 precision: 2.
tempSensor addDependent: self.
sim := BoilerSim new.
sim initChange: tempSensor on: oilValve
plus: 15 minus: 10 per: #fiveSecondEvent
atTemp: 220.
internalModels := OrderedCollection with: sim.!
initWindowSize
<<Public>><<Widget>>
"Tell the topWidget what size to open to"
| listLineHeight halfLineHeight |
listLineHeight := Font menuFont height + 12.
halfLineHeight := Font menuFont height + 6.
^200@((6*listLineHeight) + (halfLineHeight*0) - 2)!
modelReleased: who
<<Public>><<Widget>>
"The top Pane lost a model for one of its subPanes.
The whole window should close."
^true!
oilFlowSensor
<<Limited>>
^oilFlowSensor!
oilValve
<<Limited>>
^oilValve!
openView
<<Public>><<Widget>>
"create a boiler interface "
| listLineHeight aWidget aView
faultStatus1Model faultStatus2Model ignitorStatusModel valveStatusModel
topWidget min max
halfLineHeight
|
CursorManager execute change.
listLineHeight := Font menuFont height + 12.
halfLineHeight := Font menuFont height + 6.
topWidget := WTopWidget new
"model: nil;"
owner: self;
label: 'Boiler';
yourself.
topWidget := topWidget.
topWidget view minimumSize: 300 @ 200.
topWidget view whiteOnRedraw: true.
topWidget view windowType: Window noGrowDocProc.
topWidget addSubWidget:
((aWidget := WLinearView newWidget)
model: tempSensor;
owner: self).
aView := aWidget view.
min := tempSensor min. max := tempSensor max.
aView
drawBorder: #thicktLine;
framingBlock: [:box|
box origin + (0 @ (listLineHeight * 2))
extent:
box width @ (listLineHeight * 2 + halfLineHeight)];
initLowReading: min
highReading: max
"
startDegree: 90
rangeDegree: 360
"
tickMarks: (( min to: max by: 30) collect:
[:item | ((item - min) \\ 60 == 0) ifTrue: [
item printString] ifFalse: ['']
])
subTicks: 2";
extraBorder: 10".
(valveStatusModel := CalcValueInformer new)
valueBlock: [:model |
model value ifTrue: ['Oil Flowing'] ifFalse: ['Oil Valve
Closed']];
model: oilValve.
(ignitorStatusModel := CalcValueInformer new)
valueBlock: [:model |
model value ifTrue: ['Ignite'] ifFalse: ['Ignitor Off']];
model: ignitor.
(faultStatus1Model := CalcValueInformer new)
valueBlock: [:model |
model value ifTrue: ['Comb. Fault'] ifFalse: ['Combustion']];
model: combustionSensor.
(faultStatus2Model := CalcValueInformer new)
valueBlock: [:model |
model value ifTrue: ['Oil Fault'] ifFalse: ['Oil Flow']];
model: oilFlowSensor.
topWidget addSubWidget:
((aWidget := WStatusWidget new)
setNilDecodeBlock;
owner: self).
aView := aWidget view.
aView
label: 'Boiler Temp ( F)';
drawBorder: #thickbLine;
framingBlock: [:box|
box origin + (0 @ ((listLineHeight * 4)))
extent:
box width @ halfLineHeight];
yourself.
topWidget addSubWidget:
((aWidget := WStatusWidget new)
modelText: valveStatusModel boolean: oilValve;
owner: self).
aView := aWidget view.
aView
drawBorder: #bLine;
framingBlock: [:box|
box origin + (0 @ 0 )
extent:
box width @ listLineHeight];
yourself.
topWidget addSubWidget:
((aWidget := WStatusWidget new)
modelText: ignitorStatusModel boolean: ignitor;
owner: self).
aView := aWidget view.
aView
drawBorder: #bLine;
framingBlock: [:box|
box origin + (0 @ (listLineHeight * 1))
extent:
box width @ listLineHeight];
yourself.
topWidget addSubWidget:
((aWidget := WStatusWidget new)
modelText: faultStatus1Model boolean: combustionSensor;
owner: self).
aView := aWidget view.
aView
drawBorder: #double;
framingBlock: [:box|
box origin + (0 @ (box height - (listLineHeight * 1) - 2))
extent:
box width // 2 @ listLineHeight];
yourself.
topWidget addSubWidget:
((aWidget := WStatusWidget new)
modelText: faultStatus2Model boolean: oilFlowSensor;
owner: self).
aView := aWidget view.
aView
drawBorder: #double;
framingBlock: [:box|
box origin + (box width // 2 @ (box height - (listLineHeight
* 1) - 2))
extent:
box width // 2 @ listLineHeight];
yourself.
internalModels add: ignitorStatusModel;
add: valveStatusModel;
add: faultStatus1Model;
add: faultStatus2Model.
" add: topWidget"
topWidget open.
topWidget addWindow.!
release
<<Public>>
super release.
internalModels isNil ifFalse: [
internalModels do: [:each |
each releaseFirst: self.
].
].
internalModels := nil.
oilValve releaseFirst: self.
oilValve := nil.
ignitor releaseFirst: self.
ignitor := nil.
oilFlowSensor releaseFirst: self.
oilFlowSensor := nil.
combustionSensor releaseFirst: self.
combustionSensor := nil.
tempSensor releaseFirst: self.
tempSensor := nil.!
resetFault
<<Public>>
"Try to reset the fault yourself"
combustionSensor toFalse.!
tempSensor
<<Limited>>
"My temp sensor"
^tempSensor!
turnOff
<<Public>>
oilValve toFalse.!
turnOn
<<Public>>
self faultExists ifTrue: [^false].
oilValve open.
"wait for the oilValve to open"
[self faultExists or: [oilValve value]] whileFalse: [].
self faultExists ifFalse: [
ignitor ignite.
^true
].
^false!
update: who
<<Public>><<Dependency>>
((who == oilFlowSensor | (who == combustionSensor))
and: [self faultExists]) ifTrue: [
^self changedDetail: #fault
].
"Remind people a fault condition exists"
self faultExists ifTrue: [self changedDetail: #fault].
who == tempSensor ifTrue: [
tempSensor value >= 150 ifTrue: [
^self changedDetail: #atTemperature
].
].!
update: who with: detail
<<Public>><<Dependency>>
detail == #release ifTrue: [
self release.
^self
].
self update: who.! !
"\TeXCommand
\startClassDef{Furnace}{TestHeating}
\setVersion{1:48 on Oct 4, 1991}
\setHierarchy{{TestHeating}{Object}}
\endClassDef
"!
TestHeating subclass: #Furnace
instanceVariableNames:
'heatingSystem state boiler blower startCoolingTime
activateDesired internalModels '
classVariableNames: ''
poolDictionaries: ''.
"\TeXCommand
\startClassSection{Comment}
"!
Furnace
comment:
'
A furnace is composed of:
Boiler
Blower
Internal values:
startCoolingTime
activateDesired
The object <state> is a Furnace state and
handles validating state moves (basically
it just prevents missspellings.)
'
.
!
"\TeXCommand
\startClassSection{Summary}
"!
"
************* Class Methods Summary ************
----Public----
newForSystem: aSystem
*********** Instance Methods Summary ***********
----Public----
activate Turn on the furnace if you can
deactivate
faultExists
isOn
release
resetFault Try to reset the fault yourself
shutDown
startUp Don't need to do anything to start up
state
Dependency
update: who
update: who with: detail
Widget
initWindowSize Tell the topWidget what size to open to
initWindowSize: who Tell the topWidget what size to open to
openAllViews Bring up a window on the activate switch
openView Bring up a window on the activate switch
----Limited----
blower
boiler
clock
----Private----
activated We are now on
initForSystem: aSystem
stable
The stable state of the system, with a furnace ready
to run
startBlower
startBoiler
startCooling
stopBlower
stopBoiler
***************** End Summary ******************
"!
!Furnace class methods !
newForSystem: aSystem
<<Public>>
^super new initForSystem: aSystem.! !
!Furnace methods !
activate
<<Public>>
"Turn on the furnace if you can"
self faultExists ifTrue: [
^false
].
(state isStopping) ifTrue: [
activateDesired := true.
state isStable ifTrue: [^self stable]. "Update ourselves"
].!
activated
<<Private>>
"We are now on"
state activated.
self changedDetail: #activated.!
blower
<<Limited>>
^blower!
boiler
<<Limited>>
^boiler!
clock
<<Limited>>
heatingSystem isNil ifTrue: [^C].
^heatingSystem clock!
deactivate
<<Public>>
activateDesired := false.
state isStartingBlower ifTrue: [
^self stopBlower
].
(state isStartingBoiler) | (state isActivated) ifTrue: [
^self stopBoiler
].!
faultExists
<<Public>>
^boiler faultExists!
initForSystem: aSystem
<<Private>>
heatingSystem := aSystem.
state := FurnaceState new.
state addDependent: self.
state stable.
activateDesired := false.
blower := Blower new.
blower addDependent: self.
boiler := Boiler new.
boiler addDependent: self.
internalModels := OrderedCollection new.
self clock addDependent: self.!
initWindowSize
<<Public>><<Widget>>
"Tell the topWidget what size to open to"
| listLineHeight halfLineHeight |
listLineHeight := Font menuFont height + 12.
^200@(listLineHeight)!
initWindowSize: who
<<Public>><<Widget>>
"Tell the topWidget what size to open to"
| listLineHeight halfLineHeight |
listLineHeight := Font menuFont height + 12.
^150@(listLineHeight)!
isOn
<<Public>>
^state isActivated!
openAllViews
<<Public>><<Widget>>
"Bring up a window on the activate switch"
boiler openView.
blower openView.
self openView.!
openView
<<Public>><<Widget>>
"Bring up a window on the activate switch"
|simple topWidget statusModel statusModel2|
(statusModel := CalcValueInformer new)
valueBlock: [:model |
(model isStable ifFalse: [model state printString]
ifTrue: ['Deactivated'])];
model: state.
(statusModel2 := CalcValueInformer new)
valueBlock: [:model |
(model isActivated)];
model: state.
simple := (SimpleWidgetWindow new createStatusOnText: statusModel boolean:
statusModel2).
simple
owner: self.
topWidget := simple topWidget.
topWidget label: 'Furnace'.
topWidget view windowType: Window noGrowDocProc.
"topWidget view closeable: false."
internalModels add: statusModel;
add: statusModel2.
topWidget open; addWindow.!
release
<<Public>>
super release.
internalModels isNil ifFalse: [
internalModels do: [:each |
each releaseFirst: self.
].
].
internalModels := nil.
self clock release: self.
state releaseFirst: self.
state := nil.
boiler releaseFirst: self.
boiler := nil.
blower releaseFirst: self.
blower := nil.
heatingSystem := nil.!
resetFault
<<Public>>
"Try to reset the fault yourself"
boiler resetFault!
shutDown
<<Public>>
self deactivate.!
stable
<<Private>>
"The stable state of the system, with a furnace ready
to run"
activateDesired ifTrue: [
self faultExists ifFalse: [
activateDesired := false.
^self startBlower
].
].
^state stable.!
startBlower
<<Private>>
state startingBlower.
^blower turnOn!
startBoiler
<<Private>>
state startingBoiler.
boiler turnOn ifFalse: [
^self stopBoiler
].!
startCooling
<<Private>>
startCoolingTime := self clock currentTime.
^state cooling!
startUp
<<Public>>
"Don't need to do anything to start up"!
state
<<Public>>
^state value!
stopBlower
<<Private>>
state stoppingBlower.
^blower turnOff.!
stopBoiler
<<Private>>
state stoppingBoiler1.
^boiler turnOff.!
update: who
<<Public>><<Dependency>>!
update: who with: detail
<<Public>><<Dependency>>
detail == #release ifTrue: [
self release.
^self
].
(detail ~~ #fiveSecondEvent) & (detail ~~#secondEvent) ifTrue: [
"
Transcript nextPutAll: detail printString,' by: ', who printString;cr.
"
].
detail == #fault ifTrue: [
(state isStartingBoiler) | (state isActivated)
ifTrue: [
self stopBoiler.
].
(state isStartingBlower) ifTrue: [
self stopBlower.
].
self changedDetail: #fault.
^self
].
"Remind people a fault condition exists"
self faultExists ifTrue: [self changedDetail: #fault].
detail == #atSpeed ifTrue: [
state isStartingBlower ifTrue: [
^self startBoiler
].
^self
].
detail == #atTemperature ifTrue: [
Transcript nextPutAll: detail printString,' by: ', who printString;cr.
state isStartingBoiler ifTrue: [
^self activated
].
^self
].
detail == #fiveSecondEvent ifTrue: [
(state isCooling) ifTrue: [
(self clock currentTime subtractTime: startCoolingTime)
minutes < 1 ifFalse: [
^self stable
].
].
(state isStoppingBoiler1) ifTrue: [
^state stoppingBoiler2
].
(state isStoppingBoiler2) ifTrue: [
^self stopBlower
].
(state isStoppingBlower) ifTrue: [
^self startCooling
].
(state isStable) ifTrue: [
self stable
]
].
self update: who.! !
"\TeXCommand
\startClassDef{Blower}{Components}
\setVersion{1:48 on Oct 4, 1991}
\setHierarchy{{Components}{TestHeating}{Object}}
\endClassDef
"!
Components subclass: #Blower
instanceVariableNames:
'speed on internalModels '
classVariableNames: ''
poolDictionaries: ''.
"\TeXCommand
\startClassSection{Comment}
"!
Blower
comment:
'
This is a Furnace Blower.
'
.
!
"\TeXCommand
\startClassSection{Summary}
"!
"
************* Class Methods Summary ************
----Public----
new
*********** Instance Methods Summary ***********
----Public----
isAccelerating
isOff
isOn
isSlowing
release
speed
turnOff
turnOn
Dependency
update: who
update: who with: detail
Widget
initWindowSize Tell the topWidget what size to open to
modelReleased: who
The top Pane lost a model for one of its subPanes.
The whole window should close.
openView create a blower interface
----Private----
atSpeedValue
initialize
--UNSPECIFIED--
Old
openViewOld
***************** End Summary ******************
"!
!Blower class methods !
new
<<Public>>
^super new initialize! !
!Blower methods !
atSpeedValue
<<Private>>
^120!
initialize
<<Private>>
| sim |
on := BooleanInformer new.
on toFalse.
speed := IntervalInformer new.
speed min: 0 max: 300 precision: 1.
speed addDependent: self.
sim := BlowerSim new.
internalModels := OrderedCollection with: sim.
sim initChange: speed on: on
plus: 10 minus: 20 per: #fiveSecondEvent
atSpeed: (self atSpeedValue).!
initWindowSize
<<Public>><<Widget>>
"Tell the topWidget what size to open to"
| listLineHeight halfLineHeight |
listLineHeight := Font menuFont height + 12.
halfLineHeight := Font menuFont height + 6.
^200@((3*listLineHeight) + (halfLineHeight*1))!
isAccelerating
<<Public>>
^on value & (self isOn not)!
isOff
<<Public>>
^speed value == 0!
isOn
<<Public>>
^speed value >= (self atSpeedValue)!
isSlowing
<<Public>>
^on value not & (self isOff not)!
modelReleased: who
<<Public>><<Widget>>
"The top Pane lost a model for one of its subPanes.
The whole window should close."
^true!
openView
<<Public>><<Widget>>
"create a blower interface "
| listLineHeight aWidget aView
statusModel
topWidget min max
halfLineHeight
|
CursorManager execute change.
listLineHeight := Font menuFont height + 12.
halfLineHeight := Font menuFont height + 6.
topWidget := WTopWidget new
"model: nil;"
owner: self;
label: 'Blower';
yourself.
topWidget := topWidget.
topWidget view minimumSize: 300 @ 200.
topWidget view whiteOnRedraw: true.
topWidget view windowType: Window noGrowDocProc.
topWidget addSubWidget:
((aWidget := WLinearView newWidget)
model: speed;
owner: self).
aView := aWidget view.
min := speed min. max := speed max.
aView
" drawBorder: #thicktLine; "
framingBlock: [:box|
box origin + (0 @ (listLineHeight * 1))
extent:
box width @ (listLineHeight * 2 + halfLineHeight)];
initLowReading: min
highReading: max
tickMarks: (( min to: max by: 20) collect:
[:item | ((item - min) \\ 60 == 0) ifTrue: [
item printString] ifFalse: ['']
])
subTicks: 1";
extraBorder: 10".
(statusModel := CalcValueInformer new)
valueBlock: [:model |
model value ifTrue: ['Blower on'] ifFalse: ['Blower off']];
model: on.
topWidget addSubWidget:
((aWidget := WStatusWidget new)
setNilDecodeBlock;
owner: self).
aView := aWidget view.
aView
label: 'Blower Speed (RPM)';
" drawBorder: #thickbLine; "
framingBlock: [:box|
box origin + (0 @ ((listLineHeight * 3)))
extent:
box width @ halfLineHeight];
yourself.
topWidget addSubWidget:
((aWidget := WStatusWidget new)
modelText: statusModel boolean: on;
owner: self).
aView := aWidget view.
aView
drawBorder: #bLine;
framingBlock: [:box|
box origin + (0 @ 0 )
extent:
box width @ listLineHeight];
yourself.
internalModels add: statusModel.
" add: topWidget"
topWidget open.
topWidget addWindow.!
openViewOld
<<Old>>
|simple topWidget|
simple := (SimpleWidgetWindow new createSwitchOn: on).
simple
owner: self.
topWidget := simple topWidget.
topWidget label: 'Blower On'.
topWidget view windowType: Window noGrowDocProc.
"topWidget view closeable: false."
topWidget open.
topWidget addWindow.
simple := (SimpleWidgetWindow new createDialOn: speed).
simple
owner: self.
topWidget := simple topWidget.
topWidget label: 'Blower speed'.
simple mainWidget view
initLowReading: speed min
highReading: speed max
startDegree: 100
rangeDegree: 340
tickMarks: ((speed min to: speed max by: 20) collect: [:item |
item printString])
subTicks: 4.
topWidget open.
topWidget addWindow.!
release
<<Public>>
super release.
internalModels isNil ifFalse: [
internalModels do: [:each |
each releaseFirst: self.
].
].
internalModels := nil.
on releaseFirst: self.
on := nil.
speed releaseFirst: self.
speed := nil.!
speed
<<Public>>
^speed value!
turnOff
<<Public>>
on toFalse!
turnOn
<<Public>>
on toTrue!
update: who
<<Public>><<Dependency>>
who == speed ifTrue: [
((speed value >= (self atSpeedValue)) and: [on value]) ifTrue: [
self changedDetail: #atSpeed
].
((speed value == 0) and: [on value not]) ifTrue: [
self changedDetail: #stopped
].
].!
update: who with: detail
<<Public>><<Dependency>>
detail == #release ifTrue: [
self release.
^self
].
self update: who.! !
"\TeXCommand
\startClassDef{Valve}{BooleanInformer}
\setVersion{1:48 on Oct 4, 1991}
\setHierarchy{{BooleanInformer}{Informer}{Object}}
\endClassDef
"!
BooleanInformer subclass: #Valve
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''.
"\TeXCommand
\startClassSection{Comment}
"!
Valve
comment:''
.
!
"\TeXCommand
\startClassSection{Summary}
"!
"
************* Class Methods Summary ************
*********** Instance Methods Summary ***********
--UNSPECIFIED--
close
open
printOn: aStream
Append the ASCII representation of the receiver to
aStream.
valueText
***************** End Summary ******************
"!
!Valve class methods ! !
!Valve methods !
close
self toFalse!
open
self toTrue!
printOn: aStream
"Append the ASCII representation of the receiver to
aStream."
self class printOn: aStream.
aStream nextPut: $(.
aStream nextPutAll: self valueText.
aStream nextPut: $).!
valueText
^value ifTrue: ['open'] ifFalse: ['closed']! !